<template>
    <div class="permission-container">
        <!-- 搜索区域 -->
        <el-card class="search-card">
            <el-form :model="searchForm" :inline="true" class="search-form">
                <el-form-item label="名称">
                    <el-input v-model="searchForm.permissionName" placeholder="请输入菜单名称/编码" clearable />
                </el-form-item>
                <el-form-item label="状态">
                    <el-select v-model="searchForm.permissionState" placeholder="请选择" clearable>
                        <el-option label="启用" :value="1" />
                        <el-option label="停用" :value="0" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="handleSearch">查询</el-button>
                    <el-button @click="handleReset">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>

        <!-- 操作按钮区域 -->
        <el-card class="action-card">
            <el-button type="primary" @click="handleAdd">新增</el-button>
            <el-button type="danger" :disabled="multipleSelection.length === 0"
                @click="handleBatchDelete">批量删除</el-button>
        </el-card>

        <!-- 菜单树形表格 -->
        <el-card class="table-card">
            <el-table ref="tableRef" :data="tableData" row-key="permissionId"
                :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" height="500px"
                @selection-change="handleSelectionChange" style="width: 100%">
                <el-table-column type="selection" width="55" fixed="left" />
                <el-table-column type="index" label="序号" width="80" fixed="left" />
                <el-table-column prop="permissionName" label="菜单名称" min-width="220" />
                <el-table-column prop="routePath" label="路由" min-width="160" />
                <el-table-column label="操作" width="160" fixed="right">
                    <template #default="{ row }">
                        <el-button link size="small" type="primary" @click="handleEdit(row)">编辑</el-button>
                        <el-button link size="small" type="danger" @click="handleDelete(row)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-card>

        <!-- 新增/编辑对话框 -->
        <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px" @close="handleDialogClose">
            <el-form ref="formRef" :model="form" :rules="formRules" label-width="100px">
                <el-form-item label="菜单名称 *" prop="permissionName">
                    <el-input v-model="form.permissionName" placeholder="请输入菜单名称" />
                </el-form-item>
                <el-form-item label="上级菜单" prop="permissionParentId">
                    <el-tree-select v-model="form.permissionParentId" :data="parentTreeOptions"
                        :props="{ value: 'id', label: 'label', children: 'children' }" node-key="id" check-strictly
                        clearable :default-expanded-keys="expandedKeys" filterable placeholder="请选择上级菜单"
                        style="width: 220px" />
                </el-form-item>
                <el-form-item label="路由" prop="routePath">
                    <el-input v-model="form.routePath" placeholder="例如: /system/menu" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span class="dialog-footer">
                    <el-button @click="dialogVisible = false">取消</el-button>
                    <el-button type="primary" @click="handleSave">保存</el-button>
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, nextTick } from 'vue'
import { ElMessage, ElMessageBox, type FormRules, type FormInstance } from 'element-plus'
import myaxios from '@/http/MyAxios'
// 搜索表单
const searchForm = reactive({
    permissionName: '',
    permissionState: null as number | null
})

// 表格
const tableData = ref<any[]>([])
const multipleSelection = ref<any[]>([])
const tableRef = ref()

// 对话框与表单
const dialogVisible = ref(false)
const dialogTitle = ref('')
const isEdit = ref(false)
const formRef = ref<FormInstance>()
const form = reactive({
    permissionId: null as number | null,
    permissionName: '',
    permissionParentId: null as number | null,
    routePath: ''
})

const formRules: FormRules = {
    permissionName: [{ required: true, message: '请输入名称', trigger: 'blur' }]
}

// 父级菜单树（用于 el-tree-select）
const parentTreeOptions = ref<any[]>([])
// 默认展开到的节点路径（祖先ID集合）
const expandedKeys = ref<Array<string | number>>([])
const mapToTreeOptions = (nodes: any[]): any[] => {
    return (nodes || []).map(n => ({
        id: n.permissionId ?? n.id ?? n.value,
        label: n.permissionName ?? n.label ?? n.name,
        children: mapToTreeOptions(n.children || [])
    }))
}

const getParentTreeOptions = (): Promise<void> => {
    return myaxios({ url: '/api/Permission/GetParentPermissionOptions', method: 'get' })
        .then(res => {
            const raw = res.data || []
            if (Array.isArray(raw) && (raw.length === 0 || ('id' in raw[0] || 'label' in raw[0]))) {
                parentTreeOptions.value = raw
            } else {
                parentTreeOptions.value = mapToTreeOptions(raw)
            }
            // 如果已有选中的父ID，则计算其祖先路径用于默认展开
            if (form.permissionParentId) {
                expandedKeys.value = findPathIds(parentTreeOptions.value, form.permissionParentId)
            }
        })
        .catch(err => {
            console.log('获取父级菜单树失败:', err)
        })
}

// 计算从根到目标ID的路径（包含目标本身）
const findPathIds = (nodes: any[], targetId: string | number): Array<string | number> => {
    const path: Array<string | number> = []
    const equals = (a: any, b: any) => String(a) === String(b)
    const dfs = (arr: any[], stack: Array<string | number>): boolean => {
        for (const n of arr || []) {
            const id = n.id ?? n.permissionId ?? n.value
            const next = [...stack, id]
            if (equals(id, targetId)) {
                path.push(...next)
                return true
            }
            if (n.children && n.children.length) {
                if (dfs(n.children, next)) return true
            }
        }
        return false
    }
    dfs(nodes || [], [])
    return path
}

// 工具函数
const formatType = (t: number) => (t === 2 ? '按钮' : '菜单')

// 列表
const mapTree = (nodes: any[]): any[] => {
    return (nodes || []).map(n => ({
        permissionId: n.permissionId ?? n.id ?? n.value,
        permissionName: n.permissionName ?? n.label ?? n.name,
        routePath: n.routePath ?? n.path ?? '',
        parentId: n.parentId ?? 0,
        permissionState: n.permissionState ?? n.state ?? 1,
        hasChildren: !!(n.children && n.children.length),
        children: mapTree(n.children || [])
    }))
}

const filterTreeBySearch = (nodes: any[]): any[] => {
    const nameKey = (x: any) => String(x.permissionName || '').toLowerCase()
    const match = (x: any) => {
        const byName = !searchForm.permissionName || nameKey(x).includes(String(searchForm.permissionName).toLowerCase())
        const byState = searchForm.permissionState === null || x.permissionState === searchForm.permissionState
        return byName && byState
    }
    const dfs = (arr: any[]): any[] => {
        const res: any[] = []
        for (const it of arr) {
            const children = dfs(it.children || [])
            if (match(it) || children.length) {
                res.push({ ...it, children })
            }
        }
        return res
    }
    return dfs(nodes)
}

const getPermissionTree = () => {
    myaxios({ url: '/api/Permission/GetPermissionTree', method: 'get', params: { parentid: 0 } })
        .then(res => {
            const raw = res.data
            const mapped = mapTree(raw)
            tableData.value = filterTreeBySearch(mapped)
            // 默认仅展开父级（根节点）
            nextTick(() => {
                try {
                    for (const r of tableData.value || []) {
                        tableRef.value?.toggleRowExpansion?.(r, true)
                    }
                } catch { }
            })
        })
        .catch(err => {
            console.log(err)
            ElMessage.error('获取菜单树失败')
        })
}

// 搜索与重置
const handleSearch = () => {
    getPermissionTree()
}
const handleReset = () => {
    searchForm.permissionName = ''
    searchForm.permissionState = null
    getPermissionTree()
}

// 选择变化
const handleSelectionChange = (selection: any[]) => {
    multipleSelection.value = selection
}

// 表单重置
const resetForm = () => {
    form.permissionId = null
    form.permissionName = ''
    form.permissionParentId = null
    form.routePath = ''
    formRef.value?.clearValidate()
}

const handleDialogClose = () => {
    resetForm()
}

// 新增
const handleAdd = async () => {
    dialogTitle.value = '新增菜单'
    isEdit.value = false
    resetForm()
    dialogVisible.value = true
    await getParentTreeOptions()
    expandedKeys.value = []
}

// 编辑
const handleEdit = async (row: any) => {
    dialogTitle.value = '编辑菜单'
    isEdit.value = true
    resetForm()
    dialogVisible.value = true
    await getParentTreeOptions()

    form.permissionId = row.permissionId ?? null
    form.permissionName = row.permissionName ?? ''
    const pid = (row.parentId ?? row.permissionParentId ?? null)
    form.permissionParentId = (pid === 0 || pid === '0') ? null : pid
    form.routePath = row.routePath ?? ''
    if (form.permissionParentId) {
        expandedKeys.value = findPathIds(parentTreeOptions.value, form.permissionParentId)
    } else {
        expandedKeys.value = []
    }
}

// 保存
const handleSave = () => {
    formRef.value?.validate(valid => {
        if (!valid) {
            ElMessage.warning('请填写必填项')
            return
        }
        const url = isEdit.value ? '/api/Permission/UpdatePermission' : '/api/Permission/CreatePermission'
        const payload = { ...form, parentId: form.permissionParentId ?? 0 }
        myaxios({ url, method: 'post', data: payload })
            .then(res => {
                if (res.data && res.data.code === 200) {
                    ElMessage.success(res.data.message || '保存成功')
                    dialogVisible.value = false
                    getPermissionTree()
                } else {
                    ElMessage.error(res.data?.message || '保存失败')
                }
            })
            .catch(err => {
                console.log(err)
                ElMessage.error('保存失败')
            })
    })
}

// 删除
const handleDelete = (row: any) => {
    ElMessageBox.confirm('确认删除该菜单吗？', '警告', { type: 'warning' })
        .then(() => {
            myaxios({ url: '/api/Permission/DeletePermission', method: 'delete', params: { permissionId: row.permissionId } })
                .then(res => {
                    if (res.data && res.data.code === 200) {
                        ElMessage.success(res.data.message || '删除成功')
                        getPermissionTree()
                    } else {
                        ElMessage.error(res.data?.message || '删除失败')
                    }
                })
                .catch(err => {
                    console.log(err)
                    ElMessage.error('删除失败')
                })
        })
        .catch(() => {
            ElMessage({ type: 'info', message: '已取消' })
        })
}

// 批量删除
const handleBatchDelete = () => {
    if (multipleSelection.value.length === 0) {
        ElMessage.warning('请选择要删除的菜单')
        return
    }
    ElMessageBox.confirm('确认删除选中的菜单吗？', '警告', { type: 'warning' })
        .then(() => {
            const ids = multipleSelection.value.map((x: any) => x.permissionId)
            myaxios({ url: '/api/Permission/DeletePermissions', method: 'post', data: { ids } })
                .then(res => {
                    if (res.data && res.data.code === 200) {
                        ElMessage.success(res.data.message || '删除成功')
                        getPermissionTree()
                    } else {
                        ElMessage.error(res.data?.message || '删除失败')
                    }
                })
                .catch(err => {
                    console.log(err)
                    ElMessage.error('删除失败')
                })
        })
        .catch(() => {
            ElMessage({ type: 'info', message: '已取消' })
        })
}

// 初始化
onMounted(() => {
    getPermissionTree()
})
</script>

<style scoped>
.permission-container {
    padding: 20px;
}

.search-card,
.action-card,
.table-card {
    margin-bottom: 20px;
}

.search-form .el-form-item {
    margin-bottom: 0;
}

.el-input,
.el-select {
    width: 200px;
}
</style>
